package com.qdsg.modulesihealsdk.detectStrategy.strategy.bfStrategy;

import android.content.Context;

import com.example.moduleutils.LogUtil;
import com.google.gson.Gson;
import com.qdsg.modulesihealsdk.detectStrategy.control.StrategyCallback;
import com.qdsg.modulesihealsdk.entity.BodyFatResultEntity;
import com.example.moduleutils.CachedThreadPoolSingleton;
import com.qdsg.modulesihealsdk.utils.SihealSdkConstant;
import com.qdsg.modulesihealsdk.detectStrategy.control.DetectBusiness;
import com.qdsg.modulesihealsdk.utils.SihealUtil;
import com.siheal.device.reader.measure.BodyFatReader;
import com.siheal.device.reader.measure.HeightWeightReader;
import com.siheal.device.reader.singlechip.DataChannelReader;
import com.siheal.entitys.device.DeviceOp;
import com.siheal.entitys.measure.BodyFatEntity;
import com.siheal.entitys.measure.HeightWeightEntity;
import com.siheal.exception.BasicException;

import java.text.DecimalFormat;

/**
 * @Description
 * @Author WuJianFeng
 * @Date 2022/11/21 11:53
 */
public class BfStrategy implements DetectBusiness {
    private DataChannelReader dataChannelReader;
    private BodyFatReader bodyFatReader;
    private HeightWeightReader heightWeightReader;
    private int age = 0;
    private int gender = 0;
    private Context context;
    private BfCallback bfCallback;
    private int progress = 0;

    /**
     *
     * haveGetReceive：是否已出值标志，防止出值后还去调用process方法
     */
    private Boolean haveGetReceive = false;
    @Override
    public void dealDetect(Context context, StrategyCallback strategyCallback) {
        this.context = context;
        haveGetReceive = false;
        progress = 0;
        if (strategyCallback instanceof BfCallback){
            bfCallback = (BfCallback)strategyCallback;
            bfCallback.detectProgress(0);
            detectBodyFat();
        }
    }

    public BfStrategy initData(int age, int gender){
        this.age = age;
        this.gender = gender;
        return this;
    }

    @Override
    public void stopThread() {
        try {

            if (bodyFatReader != null){
                bodyFatReader.stopRead();
                bodyFatReader = null;
            }
            if (heightWeightReader != null){
                heightWeightReader.stopRead();
                heightWeightReader = null;
            }

        }catch (Exception e){

        }
        if (bfCallback != null){
            bfCallback = null;
        }
        haveGetReceive = false;
    }

    private void detectBodyFat(){
        dataChannelReader = (new DataChannelReader(SihealSdkConstant.channelID_HWBMI, context){
            // 数据通道切换成功，开始调用身高体重读值方法
            @Override
            public void resultReceived(DeviceOp result) {

                heightWeightReader = (new HeightWeightReader(context) {
                    //身高体重数据获取成功，开始做后续数据处理，当前操作将结果数据回显至H5页面
                    //获取一次结果(最终结果)，在此方法中接收检测结果
                    @Override
                    public void resultReceived(HeightWeightEntity result) {
                        startBodyFat(bfCallback,result);
                        fakeProgress();
                        LogUtil.logAndWrite("__bf-hw-resultReceived",result.toString());
                    }

                    //无需处理
                    @Override
                    public void process(HeightWeightEntity middleResult) {
                        String data = new Gson().toJson(middleResult);
                        LogUtil.logAndWrite("__bf-hw-process",data);
                        if (middleResult != null){
                            if (middleResult.getHeight() == 0f && middleResult.getWeight() == 0f){
                                detectBodyFat();
                                return;
                            }
                        }
                        if (!haveGetReceive && bfCallback != null){
                            bfCallback.process(new BodyFatResultEntity(null));
                            if (progress < 50){
                                progress = progress + 10;
                                bfCallback.detectProgress(progress);
                            }
                        }

                    }
                    //调用过程中出现的异常
                    @Override
                    public void occurError(BasicException e) {

                                   /*
                                    int MEASURE_OUT_RANGE_EXCEPTION = 1001;//测量失败建议重测 weight <= 10 || weight >= 200 height <= 0 || height >= 200
                                    int MEASURE_TIME_OUT = 1005;//测量超时
                                   */
                        String data = new Gson().toJson(e);
                        LogUtil.logAndWrite("__bf-hw-occurError",data);
                        //得到数据
                        if (bfCallback != null){
                            bfCallback.occurError(e);
                        }
                    }
                });
                if (heightWeightReader != null){
                    heightWeightReader.start();
                }
            }
            //数据通道切换process方法，实现了父类抽象方法，在此无实义
            @Override
            public void process(DeviceOp middleResult) {

            }
            //数据通道切换异常处理方法
            @Override
            public void occurError(BasicException exception) {

                          /*  int ERROR_IO = 1;     //打开设备" + device.getDeviceID() + "数据通道异常
                            int ERROR_WRITE_DATA = 2;//设备" + device.getDeviceID() + "写入数据发生异常
                            int ERROR_USB_NOT_FOUND = 2001;//没有找到指定地址下(" + device.getPath() + ")设备
                            int ERROR_USB_NOT_SUPPORT = 2002;//本系统不支持USB模块
                            int ERROR_USB_UNKONW_TYPE = 2003;//未知的USB设备类型
                            int ERROR_USB_REQUEST_PERMISSION = 2004;//请求usb权限失败
                             int MEASURE_PROBE_CONFIG_ERROR = 1008;//配置文件配置错误
                            int ERROR_USB_DEVICE_OPEN = 2005;//打开usb设备错误*/
                if (bfCallback != null){
                    bfCallback.occurError(exception);
                }
            }
        });
        if (dataChannelReader != null){
            dataChannelReader.start();
        }
    }

    private void startBodyFat(BfCallback bfCallback, HeightWeightEntity heightWeightEntity){
        dataChannelReader = (new DataChannelReader(SihealSdkConstant.channelID_BF, context){
            // 数据通道切换成功，开始调用身高体重读值方法
            @Override
            public void resultReceived(DeviceOp result) {
                if (bfCallback != null){
                    bfCallback.holdHandle();
                }
                float weight = heightWeightEntity.getWeight();
                float height = heightWeightEntity.getHeight();
                //先调用身高体重reader,获取到身高体重值，然后再切换通道，将身高体重年龄性别带入体脂reader
                bodyFatReader = (new BodyFatReader(weight, height, age, gender,context) {
                    //身高体重数据获取成功，开始做后续数据处理，当前操作将结果数据回显至H5页面
                    //获取一次结果(最终结果)，在此方法中接收检测结果
                    @Override
                    public void resultReceived(BodyFatEntity result) {
                        //身高偏差值设定，measureHeightDeviate，measureWeightDeviate来源于配置文件设定
                        String data = new Gson().toJson(result);
//                                    {"age":25,"assess":"NORMAL","assessFatMass":"NORMAL","assessMuscleMass":"NORMAL","assesskeletonMass":"NORMAL","baseMetabolismValue":1775.0,"bmi":20.6,"fat":16.3,"height":184.0,"sex":"1","tixingResult":2,"tizhiResult":2,"weight":70.0,"c":"9b1204d0249449c7a897dfe4529a1553","d":0,"e":0,"gen_plan":true,"a":1668750974192,"b":0}
                        LogUtil.logAndWrite("__bf-resultReceived",data);

                        float BodyWater = Float.parseFloat(result.getFat() + "") * GetWaterStandard((String.valueOf(gender)).equals("1") ? 1 : 0, age) + GetWaterAdjust((String.valueOf(gender)).equals("1") ? 1 : 0, age);
                        DecimalFormat df1 = new DecimalFormat("#.00");
                        result.setWaterMass(Float.valueOf(df1.format(BodyWater)));
                        progress = 0;

                        //数据为0的情况手动计算
                        if (result.getBmi() == 0f){
                            result.setBmi(SihealUtil.calculateBmi(height,weight));
                        }

                        if (result.getFat() == 0f){
                            result.setFat(SihealUtil.calculateBfp(result.getBmi(),age,sex));
                        }

                        if (result.getBaseMetabolismValue() == 0f){
                            result.setBaseMetabolismValue(SihealUtil.calculateBmr(height,weight,age,sex));
                        }
                        //得到数据
                        if (bfCallback != null && !haveGetReceive){
                            bfCallback.detectProgress(100);
                            haveGetReceive = true;
                            bfCallback.resultReceived(new BodyFatResultEntity(result));
                        }
                    }

                    //无需处理
                    @Override
                    public void process(BodyFatEntity middleResult) {
                        String data = new Gson().toJson(middleResult);
                        LogUtil.logAndWrite("__bf-process",data);
                        if (!haveGetReceive && bfCallback != null){
                            bfCallback.process(new BodyFatResultEntity(middleResult));
                        }

                    }
                    //调用过程中出现的异常
                    @Override
                    public void occurError(BasicException e) {
                                   /*
                                    int MEASURE_OUT_RANGE_EXCEPTION = 1001;//测量失败建议重测 weight <= 10 || weight >= 200 height <= 0 || height >= 200
                                    int MEASURE_TIME_OUT = 1005;//测量超时
                                   */
                        String data = new Gson().toJson(e);
                        LogUtil.logAndWrite("__bf-occurError",data);

                        //得到数据
                        if (bfCallback != null){
                            bfCallback.occurError(e);
                        }
                    }
                });
                if (bodyFatReader != null){
                    bodyFatReader.start();
                }
            }
            //数据通道切换process方法，实现了父类抽象方法，在此无实义
            @Override
            public void process(DeviceOp middleResult) {}
            //数据通道切换异常处理方法
            @Override
            public void occurError(BasicException exception) {
                          /*  int ERROR_IO = 1;     //打开设备" + device.getDeviceID() + "数据通道异常
                            int ERROR_WRITE_DATA = 2;//设备" + device.getDeviceID() + "写入数据发生异常
                            int ERROR_USB_NOT_FOUND = 2001;//没有找到指定地址下(" + device.getPath() + ")设备
                            int ERROR_USB_NOT_SUPPORT = 2002;//本系统不支持USB模块
                            int ERROR_USB_UNKONW_TYPE = 2003;//未知的USB设备类型
                            int ERROR_USB_REQUEST_PERMISSION = 2004;//请求usb权限失败
                             int MEASURE_PROBE_CONFIG_ERROR = 1008;//配置文件配置错误
                            int ERROR_USB_DEVICE_OPEN = 2005;//打开usb设备错误*/
                if (bfCallback != null){
                    bfCallback.occurError(exception);
                }
            }
        });
        if (dataChannelReader != null){
            dataChannelReader.start();
        }
    }

    public static float GetWaterStandard(int gender, int age) {
        if (gender == 0) {
            if (age >= 7 && age <= 11) {
                return -1.667f;
            }
            if (age >= 12 && age <= 16) {
                return -0.7284f;
            }
            if (age >= 17 && age <= 21) {
                return -1.224f;
            }
            if (age >= 22 && age <= 26) {
                return -1.018f;
            }
            if (age >= 27 && age <= 31) {
                return -1.02f;
            }
            if (age >= 32 && age <= 36) {
                return -1.314f;
            }
            if (age >= 37 && age <= 41) {
                return -1.13f;
            }
            if (age >= 42 && age <= 46) {
                return -0.8909f;
            }
            if (age >= 47 && age <= 51) {
                return -1.372f;
            }
            if (age >= 52 && age <= 56) {
                return -1.94f;
            }
            if (age >= 57 && age <= 61) {
                return -0.8936f;
            }
            if (age >= 62 && age <= 100) {
                return -0.9815f;
            }
        } else if (gender == 1) {
            if (age >= 7 && age <= 11) {
                return -1.781f;
            }
            if (age >= 12 && age <= 16) {
                return -1.127f;
            }
            if (age >= 17 && age <= 21) {
                return -1.697f;
            }
            if (age >= 22 && age <= 26) {
                return -1.86f;
            }
            if (age >= 27 && age <= 31) {
                return -1.565f;
            }
            if (age >= 32 && age <= 36) {
                return -1.389f;
            }
            if (age >= 37 && age <= 41) {
                return -1.562f;
            }
            if (age >= 42 && age <= 46) {
                return -1.674f;
            }
            if (age >= 47 && age <= 51) {
                return -1.432f;
            }
            if (age >= 52 && age <= 56) {
                return -1.295f;
            }
            if (age >= 57 && age <= 61) {
                return -1.641f;
            }
            if (age >= 62 && age <= 100) {
                return -1.426f;
            }
        }

        return 0.0f;
    }
    public static float GetWaterAdjust(int gender, int age) {
        if (gender == 0) {
            if (age >= 7 && age <= 11) {
                return 100.7f;
            }
            if (age >= 12 && age <= 16) {
                return 73.67f;
            }
            if (age >= 17 && age <= 21) {
                return 85.25f;
            }
            if (age >= 22 && age <= 26) {
                return 80.68f;
            }
            if (age >= 27 && age <= 31) {
                return 82.3f;
            }
            if (age >= 32 && age <= 36) {
                return 90.81f;
            }
            if (age >= 37 && age <= 41) {
                return 86.77f;
            }
            if (age >= 42 && age <= 46) {
                return 79.66f;
            }
            if (age >= 47 && age <= 51) {
                return 98.82f;
            }
            if (age >= 52 && age <= 56) {
                return 122.1f;
            }
            if (age >= 57 && age <= 61) {
                return 82.92f;
            }
            if (age >= 62 && age <= 100) {
                return 87.07f;
            }
        } else if (gender == 1) {
            if (age >= 7 && age <= 11) {
                return 102.6f;
            }
            if (age >= 12 && age <= 16) {
                return 85.9f;
            }
            if (age >= 17 && age <= 21) {
                return 92.88f;
            }
            if (age >= 22 && age <= 26) {
                return 96.35f;
            }
            if (age >= 27 && age <= 31) {
                return 93.05f;
            }
            if (age >= 32 && age <= 36) {
                return 90.56f;
            }
            if (age >= 37 && age <= 41) {
                return 94.39f;
            }
            if (age >= 42 && age <= 46) {
                return 97.87f;
            }
            if (age >= 47 && age <= 51) {
                return 92.64f;
            }
            if (age >= 52 && age <= 56) {
                return 90.33f;
            }
            if (age >= 57 && age <= 61) {
                return 100.1f;
            }
            if (age >= 62 && age <= 100) {
                return 94.68f;
            }
        }
        return 0.0f;
    }



    /**
     * 假的进度条
     */
    public void fakeProgress(){
        CachedThreadPoolSingleton.getInstance().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                    if (bfCallback != null){
                        if (progress < 100){
                            progress = progress + 5;
                            bfCallback.detectProgress(progress);
                            fakeProgress();
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

}
